package com.uinnova.product.eam.service.asset.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.binary.core.exception.BinaryException;
import com.binary.core.util.BinaryUtils;
import com.google.common.collect.Lists;
import com.uinnova.product.eam.service.ICISwitchSvc;
import com.uinnova.product.eam.service.IEamCIClassApiSvc;
import com.uinnova.product.eam.service.asset.ArchitectureAssetSvc;
import com.uinnova.product.eam.service.asset.AssetContent;
import com.uinnova.product.eam.service.es.IamsESCIDesignSvc;
import com.uinnova.product.eam.service.es.IamsESCIPrivateSvc;
import com.uinnova.product.vmdb.comm.model.ci.CCcCi;
import com.uino.bean.cmdb.base.ESCIAttrDefInfo;
import com.uino.bean.cmdb.base.ESCIClassInfo;
import com.uino.bean.cmdb.base.ESCIInfo;
import com.uino.bean.cmdb.base.LibType;
import com.uino.util.sys.SysUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 架构资产
 *
 * @author zdh_c
 */
@Service
@Slf4j
public class ArchitectureAssetSvcImpl implements ArchitectureAssetSvc, AssetContent {
    @Resource
    IEamCIClassApiSvc ciClassApiSvc;
    @Resource
    ICISwitchSvc ciSwitchSvc;
    @Resource
    IamsESCIPrivateSvc esCiSvc;
    @Resource
    IamsESCIDesignSvc esDesginCiSvc;

    @Override
    public Object classAndCiProcessingByClassId(List<Long> classIds) {
        Long domainId = SysUtil.getCurrentUserInfo().getDomainId();
        List<ESCIClassInfo> classInfos = ciClassApiSvc.selectCiClassByIds(classIds);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
        List<String> classCodes = new ArrayList<>();
        for (ESCIClassInfo classInfo : classInfos) {
            classCodes.add(classInfo.getClassCode());
            Long id = classInfo.getId();
            List<ESCIAttrDefInfo> attrDefs = classInfo.getAttrDefs();
            Set<String> proNameList = attrDefs.stream().map(esciAttrDefInfo -> esciAttrDefInfo.getProName()).collect(Collectors.toSet());
            Map<String, ESCIAttrDefInfo> attrDefInfoMap = attrDefs.stream().collect(Collectors.toMap(ESCIAttrDefInfo::getProName, e -> e, (k1, k2) -> k1));
            boolean flag = false;
            // 创建时间
            if (!proNameList.contains(CREATION_TIME)) {
                flag = true;
                ESCIAttrDefInfo defInfo = new ESCIAttrDefInfo();
                attrDefs.add(defInfo);
                defInfo.setIsRequired(0);
                defInfo.setProType(7);
                defInfo.setClassId(id);
                defInfo.setCreateTime(BinaryUtils.getNumberDateTime());
                defInfo.setIsCiDisp(0);
                defInfo.setDataStatus(1);
                defInfo.setIsMajor(0);
                defInfo.setProName(CREATION_TIME);
                defInfo.setProStdName(CREATION_TIME);
                defInfo.setDomainId(domainId);
                defInfo.setDefVal("");
                defInfo.setForbidden(true);
            } else {
                ESCIAttrDefInfo createAttr = attrDefInfoMap.get(CREATION_TIME);
                if (createAttr.getProType() != 7) {
                    throw new BinaryException("分类" + classInfo.getClassName() + ":" + CREATION_TIME + "字段分类不正确，请修改分类为“日期”，或删除该字段");
                }
                if (!createAttr.isForbidden()) {
                    flag = true;
                    createAttr.setForbidden(true);
                }
            }
            // 修改时间
            if (!proNameList.contains(MODIFI_TIME)) {
                flag = true;
                ESCIAttrDefInfo updateTimeAttr = new ESCIAttrDefInfo();
                attrDefs.add(updateTimeAttr);
                updateTimeAttr.setIsRequired(0);
                updateTimeAttr.setProType(7);
                updateTimeAttr.setClassId(id);
                updateTimeAttr.setCreateTime(BinaryUtils.getNumberDateTime());
                updateTimeAttr.setIsCiDisp(0);
                updateTimeAttr.setDataStatus(1);
                updateTimeAttr.setIsMajor(0);
                updateTimeAttr.setProName(MODIFI_TIME);
                updateTimeAttr.setProStdName(MODIFI_TIME);
                updateTimeAttr.setDomainId(domainId);
                updateTimeAttr.setDefVal("");
                updateTimeAttr.setForbidden(true);
            } else {
                ESCIAttrDefInfo uodatedate = attrDefInfoMap.get(MODIFI_TIME);
                if (uodatedate.getProType() != 7) {
                    throw new BinaryException("分类" + classInfo.getClassName() + ":" + MODIFI_TIME + "字段分类不正确，请修改分类为“日期”，或删除该字段");
                }
                if (!uodatedate.isForbidden()) {
                    flag = true;
                    uodatedate.setForbidden(true);
                }
            }
            // 发布时间
            if (!proNameList.contains(RELEASE_TIME)) {
                flag = true;
                ESCIAttrDefInfo relaseTimeAttr = new ESCIAttrDefInfo();
                attrDefs.add(relaseTimeAttr);
                relaseTimeAttr.setIsRequired(0);
                relaseTimeAttr.setProType(7);
                relaseTimeAttr.setClassId(id);
                relaseTimeAttr.setCreateTime(BinaryUtils.getNumberDateTime());
                relaseTimeAttr.setIsCiDisp(0);
                relaseTimeAttr.setDataStatus(1);
                relaseTimeAttr.setIsMajor(0);
                relaseTimeAttr.setProName(RELEASE_TIME);
                relaseTimeAttr.setProStdName(RELEASE_TIME);
                relaseTimeAttr.setDomainId(domainId);
                relaseTimeAttr.setDefVal("");
                relaseTimeAttr.setForbidden(true);
            } else {
                ESCIAttrDefInfo uodatedate = attrDefInfoMap.get(RELEASE_TIME);
                if (uodatedate.getProType() != 7) {
                    throw new BinaryException("分类" + classInfo.getClassName() + ":" + RELEASE_TIME + "字段分类不正确，请修改分类为“日期”，或删除该字段");
                }
                if (!uodatedate.isForbidden()) {
                    flag = true;
                    uodatedate.setForbidden(true);
                }
            }
            // 资产状态
            if (!proNameList.contains(RELEASE_STATE)) {
                flag = true;
                ESCIAttrDefInfo stateAttr = new ESCIAttrDefInfo();
                attrDefs.add(stateAttr);
                stateAttr.setIsRequired(0);
                stateAttr.setProType(6);
                stateAttr.setEnumValues(JSONObject.toJSONString(Lists.newArrayList(DRAFT, RELEASE, CANCELLED, APPROVE, APPROVE_EDIT)));
                stateAttr.setClassId(id);
                stateAttr.setCreateTime(BinaryUtils.getNumberDateTime());
                stateAttr.setIsCiDisp(0);
                stateAttr.setDataStatus(1);
                stateAttr.setIsMajor(0);
                stateAttr.setProName(RELEASE_STATE);
                stateAttr.setProStdName(RELEASE_STATE);
                stateAttr.setDomainId(domainId);
                stateAttr.setDefVal("");
                stateAttr.setForbidden(true);
            } else {
                ESCIAttrDefInfo uodatedate = attrDefInfoMap.get(RELEASE_STATE);
                if (uodatedate.getProType() != 6) {
                    throw new BinaryException("分类" + classInfo.getClassName() + ":" + RELEASE_STATE + "字段分类不正确，请修改分类为“枚举”，或删除该字段");
                } else {
                    String enumValues = uodatedate.getEnumValues();
                    if (!BinaryUtils.isEmpty(enumValues)) {
                        List<String> enumVal = JSONArray.parseArray(enumValues, String.class);
                        if (!enumVal.contains(DRAFT)) {
                            flag = true;
                            enumVal.add(DRAFT);
                        }
                        if (!enumVal.contains(RELEASE)) {
                            flag = true;
                            enumVal.add(RELEASE);
                        }
                        if (!enumVal.contains(CANCELLED)) {
                            flag = true;
                            enumVal.add(CANCELLED);
                        }
                        if (!enumVal.contains(APPROVE)) {
                            flag = true;
                            enumVal.add(APPROVE);
                        }
                        if (!enumVal.contains(APPROVE_EDIT)) {
                            flag = true;
                            enumVal.add(APPROVE_EDIT);
                        }
                        uodatedate.setEnumValues(JSONObject.toJSONString(enumVal));
                    } else {
                        flag = true;
                        uodatedate.setEnumValues(JSONObject.toJSONString(Lists.newArrayList(DRAFT, RELEASE, CANCELLED, APPROVE, APPROVE_EDIT)));
                    }
                }
                if (!uodatedate.isForbidden()) {
                    flag = true;
                    uodatedate.setForbidden(true);
                }
            }
            if (flag) {
                ciClassApiSvc.saveOrUpdateESCIClass(classInfo);
                log.info("资产配置更新分类信息，及数据处理,分类标识：" + classInfo.getClassCode());
                // 处理Ci
                // 私有库
                CCcCi cdt = new CCcCi();
                cdt.setClassId(classInfo.getId());
                List<ESCIInfo> esciInfos = ciSwitchSvc.queryESCIInfoList(SysUtil.getCurrentUserInfo().getDomainId(), cdt, null, false, LibType.PRIVATE);
                for (ESCIInfo esciInfo : esciInfos) {
                    Map<String, Object> attrs = esciInfo.getAttrs();
                    Long createTime = esciInfo.getCreateTime();
                    try {
                        String create = sdf.format(timeFormatter.parse(createTime.toString()));
                        attrs.put(CREATION_TIME, create);
                        Long modifyTime = esciInfo.getModifyTime();
                        String modifyDateTime = sdf.format(timeFormatter.parse(modifyTime.toString()));
                        attrs.put(MODIFI_TIME, modifyDateTime);
                    } catch (ParseException e) {
                        log.error("时间转换失败");
                    }
                    attrs.put(RELEASE_STATE, DRAFT);
                }
                if (!CollectionUtils.isEmpty(esciInfos)) {
                    esCiSvc.saveOrUpdateBatch(esciInfos);
                }
                // 设计库
                List<ESCIInfo> designCiList = ciSwitchSvc.queryESCIInfoList(SysUtil.getCurrentUserInfo().getDomainId(), cdt, null, false, LibType.DESIGN);
                for (ESCIInfo esciInfo : designCiList) {
                    Map<String, Object> attrs = esciInfo.getAttrs();
                    Long createTime = esciInfo.getCreateTime();
                    try {
                        String create = sdf.format(timeFormatter.parse(createTime.toString()));
                        attrs.put(CREATION_TIME, create);
                        Long modifyTime = esciInfo.getModifyTime();
                        String modifyDateTime = sdf.format(timeFormatter.parse(modifyTime.toString()));
                        attrs.put(MODIFI_TIME, modifyDateTime);
                        attrs.put(RELEASE_TIME, create);
                    } catch (ParseException e) {
                        log.error("时间转换失败");
                    }
                    attrs.put(RELEASE_STATE, RELEASE);
                }
                if (!CollectionUtils.isEmpty(designCiList)) {
                    esDesginCiSvc.saveOrUpdateBatch(designCiList);
                }
            }
        }
        return classCodes;
    }
}
